
package com.be.beadmin.design.impl;

import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.design.dto.input.BomReviewDto;
import com.be.beadmin.design.dto.output.BomReviewEx;
import com.be.beadmin.design.entity.BomReview;
import com.be.beadmin.design.entity.BomReviewMain;
import com.be.beadmin.design.entity.BomReview_;
import com.be.beadmin.design.entity.ProductBomOverview;
import com.be.beadmin.design.mapper.BomReviewMapper;
import com.be.beadmin.design.mapper.BomReviewMapperEx;
import com.be.beadmin.design.repository.BomReviewMainRepository;
import com.be.beadmin.design.repository.BomReviewRepository;
import com.be.beadmin.design.repository.ProductBomOverviewRepository;
import com.be.beadmin.design.service.BomReviewService;
import com.be.beadmin.project.entity.BatchProduct;
import com.be.beadmin.project.entity.Info;
import com.be.beadmin.project.entity.TeamInfo;
import com.be.beadmin.project.repository.BatchProductRepository;
import com.be.beadmin.project.repository.InfoRepository;
import com.be.beadmin.project.repository.TeamInfoRepository;
import com.be.beadmin.service.entity.NotifyInfo;
import com.be.beadmin.service.repository.NotifyInfoRepository;
import com.be.beadmin.service.repository.NotifyTemplateInfoRepository;
import com.be.beadmin.service.service.NotifyTemplateInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
* @description 服务实现
* @author zmy
* @date 2023-08-29
**/
@Service
@RequiredArgsConstructor
public class BomReviewServiceImpl implements BomReviewService {

    @Autowired
    private  BomReviewRepository bomReviewRepository;
    @Autowired
    private  BomReviewMapper bomReviewMapper;
    @Autowired
    private  BomReviewMapperEx bomReviewExMapper;


    @Autowired
    private ProductBomOverviewRepository productBomOverviewRepository;

    @Autowired
    private BatchProductRepository batchProductRepository;


    @Autowired
    private NotifyTemplateInfoService notifyTemplateInfoService;

    @Autowired
    private NotifyTemplateInfoRepository notifyTemplateInfoRepository;

    @Autowired
    private NotifyInfoRepository notifyInfoRepository;


    @Autowired
    private InfoRepository infoRepository;
    @Autowired
    private TeamInfoRepository teamInfoRepository;



    @Override
    public Page<BomReviewEx> getBomReviewByPage(PageEntity pageEntity) {
            Pageable pageable = PageRequest.of(
            pageEntity.getCurrent() -1,
            pageEntity.getPageSize());
            Page<BomReview> page = bomReviewRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(BomReview_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(BomReview_.createTime).as(Date.class)));
                    }
                    return  criteriaBuilder.and(list.toArray(p));
                    }
                    , pageable);
            Page<BomReviewEx> page1 = page.map(bomReviewExMapper::toEntity);
            return page1;

    }

    @Override
    public void addBomReview(BomReviewDto bomReviewDto) throws ParseException {
        BomReview result = bomReviewRepository.findBomReviewByIdAndDelete(bomReviewDto.getId(), 0);
        if(ObjectUtil.isNotEmpty(result)) {
            throw new BeadminException("BomReview不存在,请重新查询");
        }
        BomReview res = null;
        if(bomReviewDto.getBomBeforeId() != null) {
            res = bomReviewRepository.findBomReviewByBomBeforeIdAndVersionAndVersionSecondAndChangeStatusAndDelete(bomReviewDto.getBomBeforeId(), bomReviewDto.getVersion(), bomReviewDto.getVersionSecond(), 3, 0);
//          res = bomReviewRepository.findBomReviewByBomBeforeIdAndVersionAndVersionSecondAndDelete(bomReviewDto.getBomBeforeId(), bomReviewDto.getVersion(), bomReviewDto.getVersionSecond(), 0);
        }
        if(res != null){
            res.setMaterialQty(bomReviewDto.getMaterialQty());
            bomReviewRepository.save(res);
        }
        else {
            BomReview bomReview = bomReviewMapper.toEntity(bomReviewDto);
            bomReview.setPreMaterialQty(bomReviewDto.getPreMaterialQty());
            bomReviewRepository.save(bomReview);
        }

        BatchProduct product = batchProductRepository.findBatchProductByProductCodeAndDelete(bomReviewDto.getProductCode(),0);


        // 消息通知： 工程师 ->技术经理
        //-----------------------------------------------------------------------
        // 申请人 发送 工时补录 待办  审批人
        NotifyInfo notifyInfo =new NotifyInfo();
        notifyInfo.setModuleName("设计管理");
        notifyInfo.setFuncName("BOM变更");
        notifyInfo.setNotifyDesc("非标柜体编码为["+product.getProductCode()+"]--新增BOM,待审批");
        notifyInfo.setNotifyType("待办");
        if (product.getEngineer()==null){
            notifyInfo.setSenderName("-");
        }else{
            notifyInfo.setSenderName(product.getEngineer());
        }
        notifyInfo.setSenderName(product.getEngineer());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH-mm");
        Date date = new Date();
        notifyInfo.setSendTime(df.parse(df.format(date)));

        // 工时审核没有 用户id字段，用的用户名
        notifyInfo = notifyInfoRepository.save(notifyInfo);

        Info info = infoRepository.findInfoByIdAndDelete(product.getInfoId(),0);
        TeamInfo teaminfo = teamInfoRepository.findTeamInfoByTeamIdAndCategoryAndDelete(info.getTeamId(), "技术经理", 0);
        if (teaminfo.getUserName() != null) {
            notifyTemplateInfoService.sendNotify(notifyInfo,-2,teaminfo.getUserName(),teaminfo.getUserId());
        }
    }

    @Override
    public void updateBomReview(BomReviewDto bomReviewDto) {
            BomReview bomReview = bomReviewRepository.findBomReviewById(bomReviewDto.getId());
            bomReview = bomReviewMapper.toEntity(bomReviewDto);
            bomReviewRepository.save(bomReview);
    }


    @Override
    public void delBomReview(String id) {
        BomReview bomReview = bomReviewRepository.findBomReviewById(id);
        bomReview.setDelete(1);
        bomReviewRepository.save(bomReview);
    }

    @Override
    public void delBomReviews (List<String> ids) { }


    public void confirmBomReview (String  id,int reviewState,String memo) throws ParseException {
        BomReview bomReview = bomReviewRepository.findBomReviewByIdAndDelete(id, 0);
        //若通过，生成新的bomOverview
        if(reviewState==2){
            String bomOverviewId = bomReview.getBomBeforeId();
            ProductBomOverview productBomOverview = productBomOverviewRepository.findProductBomOverviewByIdAndDelete(bomOverviewId, 0);
            ProductBomOverview bomOverview = new ProductBomOverview();
            if(productBomOverview!=null) {

                BeanUtils.copyProperties(productBomOverview, bomOverview);

                bomOverview.setMaterialQty(bomReview.getMaterialQty());
                bomOverview.setVersion(productBomOverview.getVersion() + 1);
                bomOverview.setChangeStatus(1);
                bomOverview.setId(null);
                bomOverview.setCreateId(null);
                bomOverview.setCreateName(null);
                bomOverview.setUpdateId(null);
                bomOverview.setUpdateTime(null);
                bomOverview.setDelete(0);

                productBomOverview.setIsMax(0);
                productBomOverview.setChangeStatus(1);
                productBomOverviewRepository.save(productBomOverview);
            }else{
                BeanUtils.copyProperties(bomReview, bomOverview);
                bomOverview.setChangeStatus(1);
                bomOverview.setId(null);
                bomOverview.setCreateId(null);
                bomOverview.setCreateName(null);
                bomOverview.setUpdateId(null);
                bomOverview.setUpdateTime(null);
                bomOverview.setDelete(0);
            }
            //去更新已生成的分料任务
            productBomOverviewRepository.save(bomOverview);

            // -------------消息通知------------
            // 审批通过后进行消息通知：技术经理->生产与分料组
            List<String> cateGoryList = Arrays.asList("生产人员", "生产组长", "生产经理","分料人员","分料组长","分料经理");

            BatchProduct product = batchProductRepository.findBatchProductByProductCodeAndDelete(bomReview.getProductCode(),0);
            NotifyInfo notifyInfo =new NotifyInfo();
            notifyInfo.setModuleName("设计管理");
            notifyInfo.setFuncName("Bom变更");
            notifyInfo.setNotifyDesc("非标柜体编码为["+product.getProductCode()+"]--Bom变更审批通过");
            notifyInfo.setNotifyType("通知");

            Info projectInfo = infoRepository.findInfoByIdAndDelete(product.getInfoId(), 0);
            TeamInfo teaminfo = teamInfoRepository.findTeamInfoByTeamIdAndCategoryAndDelete(projectInfo.getTeamId(), "技术经理", 0);

            if (teaminfo.getUserName()==null){
                notifyInfo.setSenderName("-");
            }else{
                notifyInfo.setSenderName(teaminfo.getUserName());
                notifyInfo.setSenderId(teaminfo.getUserId());
            }
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH-mm");
            Date date = new Date();
            notifyInfo.setSendTime(df.parse(df.format(date)));
            notifyInfo = notifyInfoRepository.save(notifyInfo);

            List<TeamInfo> teamList = teamInfoRepository.findTeamInfoByTeamIdAndCategoryInAndDelete(projectInfo.getTeamId(), cateGoryList, 0);
            Set<TeamInfo> sets = new HashSet<>(teamList);
            for (TeamInfo item: sets){
                notifyTemplateInfoService.sendNotify(notifyInfo,-1,item.getUserName(),item.getUserId());
            }
        }else if (reviewState == 3){
            // 消息通知： 驳回后技术经理->工程师
            // ---------------------------------------------
            BatchProduct product = batchProductRepository.findBatchProductByProductCodeAndDelete(bomReview.getProductCode(),0);
            NotifyInfo notifyInfo = new NotifyInfo();
            notifyInfo.setModuleName("设计管理");
            notifyInfo.setFuncName("BOM变更");
            notifyInfo.setNotifyDesc("非柜体编码为["+product.getProductCode()+"]--BOM变更审批被驳回");
            notifyInfo.setNotifyType("通知");

            Info info = infoRepository.findInfoByIdAndDelete(product.getInfoId(),0);
            TeamInfo teaminfo = teamInfoRepository.findTeamInfoByTeamIdAndCategoryAndDelete(info.getTeamId(), "技术经理", 0);

            if (teaminfo.getUserName()==null){
                notifyInfo.setSenderName("-");
            }else{
                notifyInfo.setSenderName(teaminfo.getUserName());
                notifyInfo.setSenderId(teaminfo.getUserId());
            }
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH-mm");
            Date date = new Date();
            notifyInfo.setSendTime(df.parse(df.format(date)));
            notifyInfo = notifyInfoRepository.save(notifyInfo);

            if (product.getEngineer() != null) {
                notifyTemplateInfoService.sendNotify(notifyInfo,-1,product.getEngineer(),null);
            }
        }


        //更新审核的数据
        bomReview.setChangeStatus(reviewState);
        bomReview.setMemo(memo);
        bomReviewRepository.save(bomReview);
    }

    @Override
    public int countUnreviewedBom() {
        return bomReviewRepository.countBomReviewByAndChangeStatusAndDelete(0,0);
    }

    @Autowired
    private BomReviewMainRepository bomReviewMainRepository;

    @Override
    public void postBomReview(String id) {
        BomReview bomReview = bomReviewRepository.findBomReviewById(id);
        bomReview.setChangeStatus(0);


        BomReviewMain bomReviewMain = bomReviewMainRepository.findBomReviewMainByProductCodeAndDeleteAndChangeStatus(bomReview.getProductCode(), 0, 0);
        if(bomReviewMain == null){
            bomReviewMain= new BomReviewMain();
            bomReviewMain.setBomSequence(bomReview.getBomSequence());
            bomReviewMain.setBomCode(bomReview.getBomCode());
            bomReviewMain.setChangeSuccess(bomReview.getChangeSuccess());
            bomReviewMain.setMemo(bomReview.getMemo());
            bomReviewMain.setProductCode(bomReview.getProductCode());
            bomReviewMain.setProjectName(bomReview.getProjectName());
            bomReviewMain.setUserId(bomReview.getUserId());
            bomReviewMain.setUserName(bomReview.getUserName());
            bomReviewMain.setVersion(bomReview.getVersion());
            bomReviewMain.setVersionSecond(bomReview.getVersionSecond());
            bomReviewMain.setIsMax(bomReview.getIsMax());
            bomReviewMain.setChangeStatus(bomReview.getChangeStatus());
            bomReviewMain = bomReviewMainRepository.save(bomReviewMain);
            bomReview.setReviewMainId(bomReviewMain.getId());
        }
        else{
            bomReview.setReviewMainId(bomReviewMain.getId());
        }
        bomReviewRepository.save(bomReview);
    }
}